﻿using System;
using System.Globalization;
using System.Threading;
using System.Web;
using System.Web.Security;
using FranceTriple.Dal;
using TeamFranceTriple.Config;

namespace TeamFranceTriple
{
    /// <summary>
    /// Initialisation du theme et des culture et cultureui
    /// La variable ThisMaster n'est pas encore affectée à ces étapes du cycle de vie de la requete
    /// </summary>
    public class BasePage : System.Web.UI.Page
    {
        protected SiteMaster ThisMaster;
        private String defaultCulture = TeamFranceTripleConfig.WebConfig.defaultculturewhenacceptcultureisnull.culture.ToLower();
        private String AdressIp;

        private String[] acceptLanguage;
        private String userCulture;
        private String appliedCulture;
        private CultureInfo appliedCultureInfo = null;
        private String userTheme;

        private string GetUserIp
        {
            get
            {
                //Retrouver l'adresse d'origine, même si le visiteur est derriere un proxy
                AdressIp = Request.ServerVariables["REMOTE_HOST"].ToString();
                if (Context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
                    AdressIp = Context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

                //Afin d'éviter un petit bug aux développeurs qui ont l'ip v6
                if (AdressIp == "::1")
                    AdressIp = "127.0.0.1";

                return AdressIp;
            }
        }

        protected override void InitializeCulture()
        {
            // ordre de priorité des cultures dans leur application
            // la premiere qui fonctionne est appliquée
            // 1) request http://www.teamfrancetriple.com/en-us/ http://www.teamfrancetriple.com/fr-fr/
            // 2) user    UserProfile.GetUserProfile().UserChoosenCulture
            // 3) header  Context.Request.ServerVariables["HTTP_ACCEPT_LANGUAGE"]
            // 4) default TeamFranceTripleConfig.WebConfig.defaultculturewhenacceptcultureisnull.culture

            //Culture demandée par la requete
            if (Page.RouteData.Values["culture"] != null)
            {
                appliedCulture = Page.RouteData.Values["culture"].ToString().ToLower();
                try
                {
                    UICulture = appliedCulture;
                    Culture = appliedCulture;
                    appliedCultureInfo = CultureInfo.CreateSpecificCulture(appliedCulture);
                }
                catch (CultureNotFoundException)
                {
                    // Page inconnue ? Erreur 404 pour assurer la mise à jour des moteurs de recherche
                    throw new HttpException(404, "This page don't exists anymore. (RequesterCulture): " + appliedCulture);
                }
                Thread.CurrentThread.CurrentCulture = appliedCultureInfo;
                Thread.CurrentThread.CurrentUICulture = appliedCultureInfo;

                // Cas des pages indépendantes
                if (this.Master == null)
                    return;

                //Solved: La référence à la MasterPage est Static, donc à faire après avoir appliqué les cultures
                ThisMaster = ((SiteMaster)this.Master);

                if (Session["Requester"] != null)
                {
                    ThisMaster.Requester = Session["Requester"] as Requester;

                    // Mettre à jour le cache si besoin avec la nouvelle culture choisie
                    if (ThisMaster.Requester.Culture != appliedCulture)
                    {
                        ThisMaster.Requester.Culture = appliedCulture;
                        Session["Requester"] = ThisMaster.Requester;
                    }
                    //Mettre à jour la date de dernière activité de l'utilisateur
                    Membership.GetUser(true);
                }
                else
                {
                    //Centralise le membership et le profile utilisateur dans une propriété publique
                    ThisMaster.Requester = new Requester()
                    {
                        Culture = appliedCulture.ToLower(),
                        IpAddress = this.GetUserIp,
                        IsAuthenticated = Page.User.Identity.IsAuthenticated,
                        Membership = (Session["AnonymousID"] == null) ?
                            //Met à jour la date de dernière activité
                        Membership.GetUser(true) : null,
                        Profile = UserProfile.GetUserProfile(),
                        Roles = Roles.GetRolesForUser(),
                    };
                    //Mettre à jour le cache avec les nouvelles informations
                    Session["Requester"] = ThisMaster.Requester;
                }
            }
            else
            {   //Culture du profile utilisateur
                userCulture = UserProfile.GetUserProfile().UserChoosenCulture;
                if ((Page.User.Identity.IsAuthenticated) && userCulture != String.Empty)
                {
                    appliedCulture = userCulture.ToLower();
                    Response.Redirect("~/" + appliedCulture + "/");
                }
                else
                {
                    //Culture des headers
                    if (Context.Request.ServerVariables["HTTP_ACCEPT_LANGUAGE"] != null)
                    {
                        acceptLanguage = Context.Request.ServerVariables["HTTP_ACCEPT_LANGUAGE"].Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        // Try - pour le cas d'une culture personalisée qui n'existe pas dans .NET
                        try
                        {
                            appliedCultureInfo = CultureInfo.CreateSpecificCulture(acceptLanguage[0]);
                            appliedCulture = appliedCultureInfo.Name.ToLower();
                            Response.Redirect("~/" + appliedCulture + "/");
                        }
                        catch (CultureNotFoundException)
                        {
                            // Page inconnue ? Erreur 404 pour assurer la mise à jour des moteurs de recherche
                            throw new HttpException(404, "This page don't exists anymore.(HeaderCulture): " + acceptLanguage);
                        }
                    }
                    else
                    {
                        //Culture par défaut
                        appliedCulture = defaultCulture;
                        Response.Redirect("~/" + appliedCulture + "/");
                    }
                }
            }
        }

        protected void Page_PreInit(object sender, EventArgs e)
        {
            userTheme = UserProfile.GetUserProfile().UserTheme;
            // Pour les utilisateurs anonymes et les utilisateurs authentifiés sans profil, récupérer les langues du navigateur
            if (!(Session["AnonymousID"] == null) || userTheme == String.Empty)
            {
                Page.Theme = "default";
            }
            // Récupérer la culture de l'utilisateur authentifié dans son profil, si elle existe !
            else
            {
                Page.Theme = userTheme;
            }
        }
    }
}